/* 
 * File:   Pow.cpp
 * Author: Gab'z
 * 
 * Created on 3 juin 2012, 22:43
 */

#include "Pow.h"
#include "../../../Context.h"
#include "../../literal/Stack.h"
#include "../../literal/Complex.h"

namespace calculator {

    Pow::Pow(const std::string name) : BinaryOperator(name) {
    }

    Pow::Pow(const Pow& orig) : BinaryOperator(orig._name) {
    }

    Pow::~Pow() {
    }

    std::string Pow::isExecutable() const {
        if (Context::getInstance()->getCurrentStack()->size() < 2) return false;
        const Complex* co1 = dynamic_cast<const Complex*> (Context::getInstance()->getCurrentStack()->getConstant(0));
        const Complex* co2 = dynamic_cast<const Complex*> (Context::getInstance()->getCurrentStack()->getConstant(1));
        if ((co1 != 0)
                && Context::getInstance()->getParameters()->getComplexMode() == false) return "Complex mode OFF";
        if (co2 != 0) return "Cannot compute complex power";
        return "";
    }

    Pow* Pow::clone() const {
        return new Pow(_name);
    }

    const Number* Pow::apply(const Number* n1, const Number* n2) const throw (ArithmeticException) {
        const Complex* co1 = dynamic_cast<const Complex*> (n1);
        const Complex* co2 = dynamic_cast<const Complex*> (n2);
        const SimpleNumber* sn2 = dynamic_cast<const SimpleNumber*> (n2);
        if ((co1 != 0)
                && Context::getInstance()->getParameters()->getComplexMode() == false) throw ArithmeticException("Complex mode OFF");
        if (co2 != 0) throw ArithmeticException("Cannot compute complex power");
        const Number* n;
        try {
            n = pow(n1, sn2);
        } catch (ArithmeticException& e) {
            throw;
        }
        return n;
    }
}